package com.ruicar.afs.cloud.gateway.filter;

import com.google.common.base.Strings;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.net.URISyntaxException;

import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR;

@Component
@Slf4j
@Data
@ConditionalOnProperty(prefix = "ruicar.afs.gateway",name = "dev")
public class DevRequestFilter implements GlobalFilter, Ordered {
    private static final String TARGET_HEADER = "dev_host";
    @Value("${ruicar.afs.gateway.dev}")
    private boolean isDev = false;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        if(!isDev){
            return chain.filter(exchange);
        }
        URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
        String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);
        if (url == null
                || (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {
            return chain.filter(exchange);
        }
        if(exchange.getRequest().getHeaders().containsKey(TARGET_HEADER)){
            URI uri = exchange.getRequest().getURI();
            String scheme = uri.getScheme();
            try {
                StringBuilder sb = new StringBuilder();
                sb.append(scheme).append("://");
                if (!Strings.isNullOrEmpty(uri.getRawUserInfo())) {
                    sb.append(uri.getRawUserInfo()).append("@");
                }
                sb.append(exchange.getRequest().getHeaders().getFirst(TARGET_HEADER));

                sb.append(uri.getRawPath());
                if (!Strings.isNullOrEmpty(uri.getRawQuery())) {
                    sb.append("?").append(uri.getRawQuery());
                }
                if (!Strings.isNullOrEmpty(uri.getRawFragment())) {
                    sb.append("#").append(uri.getRawFragment());
                }
                URI newURI = new URI(sb.toString());
                log.info("\n替换地址\n{}\n直接请求开发机\n{}\n路径\n{}",url.toString(),exchange.getRequest().getHeaders().getFirst(TARGET_HEADER),newURI.toString());
                exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newURI);
            } catch (URISyntaxException e) {
                throw new RuntimeException(e);
            }
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 10002;
    }
}
